home *** CD-ROM | disk | FTP | other *** search
- {---------------------------------------------------------------------
- #
- # Apple Macintosh Developer Technical Support
- #
- # MultiFinder-Aware Simple TextEdit Sample Application
- #
- # OOPTESample
- #
- # UTESample.inc1.p - Pascal Source
- #
- # Copyright © 1988, 1989 Apple Computer, Inc.
- # All rights reserved.
- #
- # Versions:
- # 1.00 04/89
- # 1.10 02/90
- # 1.11 10/92
- #
- # Components:
- # BuildOOPTESample February 1, 1990
- # MTESample.p February 1, 1990
- # OOPTESample.make February 1, 1990
- # TECommon.h February 1, 1990
- # TESampleGlue.a February 1, 1990
- # TESample.r February 1, 1990
- # TMLRules.make February 1, 1990
- # UApplication.p February 1, 1990
- # UApplication.inc1.p February 1, 1990
- # UDocument.p February 1, 1990
- # UDocument.inc1.p February 1, 1990
- # UTEDocument.p February 1, 1990
- # UTEDocument.inc1.p February 1, 1990
- # UTESample.p February 1, 1990
- # UTESample.inc1.p February 1, 1990
- #
- ---------------------------------------------------------------------}
-
- CONST
- rMenuBar = 128;
- rDocWindow = 128; { application's window }
- rAboutAlert = 128; { about alert }
-
- { The following constants are used to identify menus and their items. The menu IDs }
- { have an "m" prefix and the item numbers within each menu have an "i" prefix. }
- mApple = 128; {Apple menu}
- iAbout = 1;
-
- mFile = 129; { File menu }
- iNew = 1;
- iClose = 4;
- iQuit = 12;
-
- mEdit = 130; { Edit menu }
- iUndo = 1;
- iCut = 3;
- iCopy = 4;
- iPaste = 5;
- iClear = 6;
-
- kMinSize = 40;
- kMaxSleepTime = 60;
- kSleepTime = $7FFFFFFF;
-
- kExtremePos = 32767 - 1; { required for old region bug }
- kExtremeNeg = -32768; {kExtremePos and kExtremeNeg are used to set up
- wide open rectangles and regions.}
-
- kMaxOpenDocuments = 1; {kMaxOpenDocuments is used to determine whether
- a new document can be opened or created. We keep
- track of the number of open documents, and disable
- the menu items that create a new document when the
- maximum is reached. If the number of documents falls
- below the maximum, the items are enabled again.}
-
- (********************************************************************************************)
- (* T T E S a m p l e *)
- (********************************************************************************************)
- {$S Initialize}
- {-----------------------------------+
- | ITESample |
- +-----------------------------------}
- PROCEDURE TTESample.ITESample;
- VAR
- menuBar: Handle;
- BEGIN
- IApplication;
-
- { Read menus into menubar }
- menuBar := GetNewMBar(rMenuBar);
-
- { Install menus }
- SetMenuBar(menuBar);
- DisposeHandle(menuBar);
-
- { Add DA names to Apple menu }
- AppendResMenu(GetMenuHandle(mApple),'DRVR');
- DrawMenuBar;
-
- { Create empty mouse region }
- fMouseRgn := NewRgn;
-
- { Create a single empty document }
- DoNew;
-
- {Make sure we have a valid cursor region }
- AdjustCursor;
- END;
-
- {$S Main}
- {-----------------------------------+
- | DoIdle |
- +-----------------------------------}
- { This is called whenever we get a NULL event et al. }
- { It takes care of necessary periodic actions. For this program, }
- { it calls the DoIdle method of the current document. }
- PROCEDURE TTESample.DoIdle; OVERRIDE;
- VAR
- fTECurDoc: TTEDocument;
- BEGIN
- fTECurdoc := TTEDocument(fCurDoc);
- IF fTECurDoc <> NIL THEN
- fTECurDoc.DoIdle;
- END;
-
- {$S Main}
- {-----------------------------------+
- | AdjustMenus |
- +-----------------------------------}
- { Enable and disable menus based on the current state. The }
- { user can only select enabled menu items. We set up all the }
- { menu items before calling MenuSelect or MenuKey, since }
- { these are the only times that a menu item can be selected. }
- { Note that MenuSelect is also the only time the user will }
- { see menu items. This approach to deciding what enable/ }
- { disable state a menu item has the advantage of }
- { concentrating all the decision-making in one routine, as }
- { opposed to being spread throughout the application. Other }
- { application designs may take a different approach that may }
- { or may not be as valid. }
-
- PROCEDURE TTESample.AdjustMenus; OVERRIDE;
- VAR
- frontMost: WindowPtr;
- menu: MenuHandle;
- offset: longint;
- undo: Boolean;
- cutCopyClear: Boolean;
- paste: Boolean;
- fTECurDoc: TTEDocument;
- BEGIN
- fTECurdoc := TTEDocument(fCurDoc);
- frontMost := FrontWindow;
-
- menu := GetMenuHandle(mFile);
- IF (fDocList.NumDocs < kMaxOpenDocuments) THEN
- EnableItem(menu,iNew)
- ELSE
- DisableItem(menu,iNew);
- IF (frontMost <> NIL) THEN
- EnableItem(menu,iClose)
- ELSE
- DisableItem(menu,iClose);
-
- menu := GetMenuHandle(mEdit);
- undo := FALSE;
- cutCopyClear := FALSE;
- paste := FALSE;
- IF (frontMost <> NIL) THEN
- IF (fTECurDoc = NIL) THEN BEGIN { all editing is enabled for DA windows }
- undo := TRUE;
- cutCopyClear := TRUE;
- paste := TRUE;
- END ELSE BEGIN
- { Cut, Copy, and Clear is enabled for app. windows with selections }
- IF fTECurDoc.HaveSelection THEN
- cutCopyClear := TRUE;
- { If we have any TEXT in the scrap, enable paste }
- IF GetScrap(NIL, 'TEXT', offset) > 0 THEN
- paste := TRUE;
- END;
-
- IF undo THEN
- EnableItem(menu,iUndo)
- ELSE
- DisableItem(menu,iUndo);
- IF cutCopyClear THEN BEGIN
- EnableItem(menu,iCut);
- EnableItem(menu,iCopy);
- EnableItem(menu,iClear);
- END ELSE BEGIN
- DisableItem(menu,iCut);
- DisableItem(menu,iCopy);
- DisableItem(menu,iClear);
- END;
- IF paste THEN
- EnableItem(menu,iPaste)
- ELSE
- DisableItem(menu,iPaste);
- END;
-
- {$S Main}
- {-----------------------------------+
- | AdjustCursor |
- +-----------------------------------}
- { Change the cursor's shape, depending on its position. This also calculates a }
- { region that includes the cursor for WaitNextEvent. }
- PROCEDURE TTESample.AdjustCursor; OVERRIDE;
- VAR
- fTECurDoc: TTEDocument;
- arrowRgn,
- iBeamRgn: RgnHandle;
- mouse: Point;
- BEGIN
- fTECurdoc := TTEDocument(fCurDoc);
-
- { Notice that we don't change the cursor if front window isn't ours }
- IF (NOT(fInBackGround) AND (fTECurDoc <> NIL)) THEN BEGIN
-
- GetMouse(mouse);
- LocalToGlobal(mouse);
-
- arrowRgn := NewRgn;
- iBeamRgn := NewRgn;
-
- SetRectRgn(arrowRgn,kExtremeNeg, kExtremeNeg, kExtremePos, kExtremePos);
-
- fTECurDoc.GetVisTERgn(iBeamRgn);
-
- DiffRgn(arrowRgn,iBeamRgn,arrowRgn);
-
- IF PtInRgn(mouse,iBeamRgn) THEN BEGIN
- SetCursor(GetCursor(iBeamCursor)^^);
- CopyRgn(iBeamRgn,fMouseRgn);
- END ELSE BEGIN
- SetCursor(qd.arrow);
- CopyRgn(arrowRgn,fMouseRgn);
- END;
- DisposeRgn(arrowRgn);
- DisposeRgn(iBeamRgn);
- END;
- END;
-
- {$S Main}
- {-----------------------------------+
- | DoMenuCommand |
- +-----------------------------------}
- { This is called when an item is chosen from the menu bar (after calling }
- { MenuSelect or MenuKey). It does the right thing for each command. }
- PROCEDURE TTESample.DoMenuCommand(menuID,menuItem: integer); OVERRIDE;
- VAR
- itemHit: integer;
- daName: Str255;
- daRefNum: integer;
- window: WindowPtr;
- fTECurDoc: TTEDocument;
- BEGIN
- fTECurdoc := TTEDocument(fCurDoc);
- window := FrontWindow;
-
- CASE menuID OF
- mApple:
- CASE menuItem OF
- iAbout: { bring up alert for About }
- itemHit := Alert(rAboutAlert, NIL);
- OTHERWISE BEGIN { all non-About items in this menu are DAs et al }
- GetMenuItemText(GetMenuHandle(mApple), menuItem, daName);
- daRefNum := OpenDeskAcc(daName);
- END; { OTHERWISE }
- END; { CASE menuItem }
- mFile:
- CASE menuItem OF
- iNew:
- DoNew;
- iClose:
- BEGIN
- IF fTECurDoc <> NIL THEN BEGIN
- fDocList.RemoveDoc(fTECurDoc);
- fTECurDoc.Free;
- END ELSE BEGIN
- CloseDeskAcc(WindowPeek(fWhichWindow)^.windowKind);
- END;
-
- { make sure our current document/window references are valid }
- window := FrontWindow;
- IF window <> NIL THEN BEGIN
- fCurDoc := fDocList.FindDoc(window);
- SetPort(window);
- END ELSE BEGIN
- fCurDoc := NIL;
- END;
- END;
-
- iQuit:
- Terminate;
- END; { CASE menuItem }
- mEdit: { call SystemEdit for DA editing & MultiFinder }
- IF NOT SystemEdit(menuItem-1) THEN
- CASE menuItem OF
- iCut: fTECurDoc.DoCut;
- iCopy: fTECurDoc.DoCopy;
- iPaste: fTECurDoc.DoPaste;
- iClear: fTECurDoc.DoClear;
- END; { CASE menuItem }
- END;
- HiliteMenu(0);
- END; { doMenuCommand }
-
- {$S Main}
- {-----------------------------------+
- | HeapNeeded |
- +-----------------------------------}
- FUNCTION TTESample.HeapNeeded: Longint; OVERRIDE;
- BEGIN
- HeapNeeded := kMinSize * 1024;
- END;
-
- {$S Main}
- {-----------------------------------+
- | SleepVal |
- +-----------------------------------}
-
- { Calculate a sleep value for WaitNextEvent. This takes into account the things }
- { that DoIdle does with Idle Time. The formula used here is:
- IF we are in the foreground
- AND our document window is in front
- THEN
- SleepVal := whatever the front document says it should be
- ELSE
- SleepVal := aRealLongTime
-
- After that, SleepVal is clipped to kMaxSleepTime which is currently set
- to 60 ticks. This is to account for a Notification Manager bug wherein
- notifications don't occur while the front application is asleep. }
-
- FUNCTION TTESample.SleepVal: LongInt; OVERRIDE;
- VAR
- sleep: longint;
- fTECurDoc: TTEDocument;
- BEGIN
- sleep := kSleepTime;
- fTECurdoc := TTEDocument(fCurDoc);
- IF ((NOT fInBackGround) AND (fTECurdoc <> NIL)) THEN BEGIN
- sleep := fTECurDoc.CalcIdle;
- END;
- IF sleep > kMaxSleepTime THEN
- sleep := kMaxSleepTime;
- SleepVal := sleep;
- END;
-
- {$S Initialize}
- {-----------------------------------+
- | DoNew |
- +-----------------------------------}
- { Create a new document and window. }
- PROCEDURE TTESample.DoNew;
- VAR
- tDoc: TTEDocument;
- BEGIN
- New(tdoc);
- tDoc.ITEDocument(rDocWindow);
-
- IF tdoc <> NIL THEN
- fdocList.Adddoc(tdoc);
- END;
-
- {$S Main}
- {-----------------------------------+
- | Terminate |
- +-----------------------------------}
- { Clean up the application and exits. We close all of the windows so that }
- { they can update their documents. }
- PROCEDURE TTESample.Terminate;
- BEGIN
- { FIX: close all docs }
- ExitLoop;
- END;
-